/*
实现一个LazyMan，可以按照以下方式调用:
LazyMan(“Hank”)输出:
Hi! This is Hank!

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
//等待10秒..
Wake up after 10
Eat dinner~

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
Hi This is Hank!
Eat dinner~
Eat supper~

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper
以此类推。

总结如下：调用LazyMan的构造器 打印名字 eat 打印吃东西 sleep 等待 sleepFirst 前面的进程均先等待
故这题考的是异步相关的知识
 */
class LazyMan {
    /**
     * 构造函数
     * @param { string } name
     */
    constructor(name) {
        this.taskQueue = []; // 任务队列
        this.sayHi(name);
        // 这个加入宏队列 在链式调用的所有函数执行完后(调用栈)后再执行 开始出队依次执行函数
        setTimeout(this._run.bind(this), 0);
    }
    /**
     * 打招呼
     * @param { string } name
     */
    sayHi(name) {
        this.taskQueue.push(() => console.log(`Hi! This is ${name}!`));
        return this;
    }
    /**
     * 吃饭
     * @param { string } something
     */
    eat(something) {
        this.taskQueue.push(() => console.log(`Eat ${something}~`));
        return this;
    }
    /**
     * 睡觉
     * @param { number } time
     */
    sleep(time) {
        this.taskQueue.push(this._sleep(time));
        return this;
    }
    /**
     * 首先睡觉
     * @param { number } time
     */
    sleepFirst(time) {
        // unshift弄到队列前面
        this.taskQueue.unshift(this._sleep(time));
        return this;
    }
    /**
     * 执行任务队列
     */
    _run() {
        this.taskQueue.forEach(task => task());
    }
    /**
     * 睡觉函数
     * @param { number } time
     */
    _sleep(time) {
        return () => {
            const start = +new Date();
            while (start + time * 1000 > +new Date());
            console.log(`Wake up after ${time}s`);
        }
    }
}

// new LazyMan("Hank").sleep(3).eat("dinner");
// new LazyMan("Hank").eat("dinner").eat("supper");
new LazyMan("Hank").sleepFirst(5).eat("supper");
